﻿using Hangfire;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using RestSharp;

namespace Common
{
  public class MpToken
  {
    /// <summary>
    /// 微信token
    /// </summary>
    private static string _AccessToken = "";
    /// <summary>
    /// 末次请求 token 时间
    /// </summary>
    private static string GenTime = "";

    /// <summary>
    /// 开发者 微信小程序 APPID
    /// </summary>
    public static readonly string AppId = "wxa1a2217f19385afc";
    /// <summary>
    /// 开发者 微信小程序 AppSecret
    /// </summary>
    public static readonly string AppSecret = "ee7e2409c66a9e6a12a0de8d6b951f80";

    /// <summary>
    /// 与上一次获取时间相差100分钟，即差20分钟过期   
    /// </summary>
    private static int ExpireMin = 100;

    public static string AccessToken
    {
      get
      {
        if (string.IsNullOrEmpty(_AccessToken))
        {
          //读取不到 请求新的token
          return RefreshToken();
        }
        if (IsExpire(GenTime, NowTimeStamp()))
        {
          //token过期 重新请求
          return RefreshToken();
        }

        return _AccessToken;
      }
    }


    public static string NowTimeStamp()
    {
      return (DateTime.Now.Ticks - 621356256000000000).ToString();
    }

    /// <summary>
    /// 时间戳输出格式化时间
    /// </summary>
    /// <param name="ts"></param>
    /// <returns></returns>
    public static string TimeStampToDt(TimeSpan ts)
    {
      var utctime = new System.DateTime(1970, 1, 1);
      DateTime ldt = TimeZoneInfo.ConvertTime(utctime, TimeZoneInfo.Utc, TimeZoneInfo.Local);
      DateTime dt = ldt.Add(ts);
      return dt.ToString("yyyy-MM-dd HH:mm");
    }

    /// <summary>
    /// 判断 token 是否临近过期
    /// </summary>
    /// <returns></returns>
    private static Boolean IsExpire(string t1, string t2)
    {
      TimeSpan ts1 = new TimeSpan(long.Parse(t1));
      TimeSpan ts2 = new TimeSpan(long.Parse(t2));
      var tsDiff = ts1.Subtract(ts2).Duration();
      return tsDiff.TotalMinutes > ExpireMin ? true : false;
    }

    public static void RefreshToken1()
    {
      Serilog.Log.Error("===================");
    }
    /// <summary>
    /// 刷新 微信 accessToken 
    /// </summary>
    /// <returns></returns>
    public static string RefreshToken()
    {
      //request 微信 accesstoken                 
      var url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={AppId}&secret={AppSecret}";
      var client = new RestClient(url);
      client.Timeout = -1;
      var request = new RestRequest(Method.GET);
      IRestResponse result;
      var errCount = 0;
    redo:
      try
      {
        result = client.Execute(request);
      }
      catch (Exception e)
      {
        if (errCount < 3)
        {
          errCount++;
          goto redo;
        }
        throw;
      }

      var res = JsonConvert.DeserializeObject<Dictionary<dynamic, dynamic>>(result.Content);
      _AccessToken = res["access_token"];

      GenTime = NowTimeStamp(); //刷新时的时间戳
      TimeSpan ts = new TimeSpan(long.Parse(GenTime));
      var timeStr = TimeStampToDt(ts);
      var mm = timeStr.Substring(timeStr.Length - 2, 2);
      return _AccessToken;
    }
  }
}
